package JVM;

/**
 * 2.类装载器   classLoader   class文件在文件开头有特定的文件标示 cafe babe
 * 虚拟机自带加载器：
 * 2.1启动类加载器 （Bootstrap）  c++（根加载器）
 * 2.2扩展类加载器（Extension)   java  PlatformClassLoader
 * 2.3应用程序类加载器 （AppClassLoader）
 *    Java也叫系统类加载器，加载当前应用的classpath的所有类
 *
 * 用户自定义加载类
 * Java.lang.ClassLoader 的子类
 *
 * 2.4.1   有哪几种类加载器  如上
 * 2.4.2   双亲委派机制     （先从根加载器找）
 *         先从启动类加载器 （Bootstrap）->扩展类加载器（Extension)->
 *         应用程序类加载器 （AppClassLoader）
 *
 *         当一个类收到了类加载请求，他首先不会尝试自己去加载这个类，
 *         而是把这个"请求委派给父类去完成"，每一个层次类加载器都是如此，
 *         因此所有的加载请求都应该传送到启动类加载其中，
 *         只有当父类加载器反馈自己无法完成这个请求的时候
 *         (在它的加载路径下没有找到所需加载的Class)，
 *         子类加载器才会尝试自己去加载。
 *      采用双亲委派的一个好处是比如加载位于rt.jar包中的类java.lang.Object,不管
 *      是哪个加载器加载这个类，最终都是委托给顶层的启动类加载器进行加载，这
 *      羊就保证了使用不同的类加载器最终得到的都是同样一个Object对象。
 * 2.4.3   沙箱安全机制 （防止污染java自带的类） 如java.lang.String
 *      我们造一个java.lang 包   创一个String类 加一个main方法
 *      他会报错   说没main方法   防止污染java自身的
 *      java.lang.String   这就是沙箱安全机制
 */
public class 类装载器 {
    public static void main(String[] args) {
        classjzq();
    }
    private static void classjzq() {
//        sun.misc.Launcher//JVM的入口
        Object object =new Object();
        //System.out.println(object.getClass().getClassLoader().getParent().getParent());
        //System.out.println(object.getClass().getClassLoader().getParent());//Bootstrap  没有更上一级的加载器了 会报错
        System.out.println(object.getClass().getClassLoader());//Bootstrap 根加载器 无（由于Bootstrap是c++   所以为null）

        类装载器 jvm=new 类装载器();
        System.out.println(jvm.getClass() == 类装载器.class);//true

        System.out.println(jvm.getClass().getClassLoader().getParent().getParent());//jvm的上上一个装载
        System.out.println(jvm.getClass().getClassLoader().getParent());//jvm的上一个装载器
        System.out.println(jvm.getClass().getClassLoader());//jvm是谁装载的
    } //类装载器
}
